package bsserver;

import bsserver.response.Response;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A Threaded class which handles a single client connection to the server.
 * @author tblackstone
 */
public class ClientConnection extends Thread {

    private Socket client;
    private OutputStream out = null;
    private BufferedInputStream in = null;

    /**
     * Creates a new client Thread to handle the given socket connection
     * @param s the socket to communicate with the client through
     */
    public ClientConnection(Socket s) {
        super("ClientConnectionThread");
        client = s;
    }

    /**
     * Handles an incoming client request and response
     */
    @Override
    public void run() {

        try {

            String remoteAddress = client.getInetAddress().getHostAddress();

            System.out.println("Connection opened from " + remoteAddress);

            // Open socket input/output streams
            out = client.getOutputStream();


            in = new BufferedInputStream(client.getInputStream());

            Request request = new Request(remoteAddress, in);
            Response response = request.getResponse();
            int messageLength = response.printResponse(out);
            Main.AccessLog.logRequest(client.getInetAddress().getHostAddress(),
                    request.getRequestLine(),
                    response.getStatusCode(),
                    messageLength);


            // Flush streams and close connection
            out.flush();
            out.close();
            in.close();
            client.close();

            System.out.println("Connection closed from " +
                    client.getInetAddress().getHostAddress());

        } catch (SocketException ex) {
            System.out.println("Client disconnected");
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            Main.connectionClosed();
        }



    }
}
